package ie.dcu.spca.data.db;

import java.util.List;

import ie.dcu.spca.data.ItemDataManager;
import ie.dcu.spca.data.ItemUserDataManager;
import ie.dcu.spca.data.PriceUnitDataManager;
import ie.dcu.spca.data.ProductDataManager;
import ie.dcu.spca.data.UserDataManager;
import ie.dcu.spca.model.Bean;
import ie.dcu.spca.model.bean.Item;
import ie.dcu.spca.model.bean.Product;
import ie.dcu.spca.model.bean.User;
import ie.dcu.spca.model.dao.ItemDao;

public class DBItemDataManager extends DBBasicDataManager implements
        ItemDataManager {

    private static ItemDao iDao = new ItemDao();

    private ItemDao itemDao() {
        return iDao;
    }

    private static ProductDataManager productManager;
    private static PriceUnitDataManager unitManager;
    private static UserDataManager userManager;
    private static ItemUserDataManager iuManager;

    public DBItemDataManager() {
        super();
    }

    @Override
    public int create(int billId, int productId, double count) {
        return itemDao().insertItem(billId, productId, count);
    }

    @Override
    public Item get(int id) {
        return (Item) itemDao().selectById(id);
    }

    @Override
    public List<Item> getByBillId(int billId) {
        return itemDao().selectItemListByBillid(billId);
    }

    @Override
    public void loadDefault(ProductDataManager p, UserDataManager u,
            PriceUnitDataManager pu, ItemUserDataManager iu) {
        productManager = p;
        unitManager = pu;
        userManager = u;
        iuManager = iu;
    }

    @Override
    public void update(int id, int billId, int productId, double count) {
        Item item = (Item) itemDao().selectById(id);
        item.setBill_id(billId);
        item.setProduct_id(productId);
        item.setCount(count);
        itemDao().updateByBean(item);
    }

    @Override
    public void delete(int id) {
        itemDao().deleteById(id);
    }

    @Override
    public List<Bean> getBeanList() {
        return itemDao().selectAllBean();
    }

    @Override
    public int getId(Bean bean) {
        return ((Item) bean).getId();
    }

    @Override
    public String getName(Bean bean) {
        Item item = (Item) bean;
        Product p = productManager.get(item.getProduct_id());
        StringBuffer sb = new StringBuffer();
        Object[] values = { p.getName(), "(", p.getPrice(), "/",
                unitManager.get(p.getUnit_id()).getName(), "*",
                item.getCount(), "=",
                priceFormat(item.getCount() * p.getPrice()), "):",
                getUserWeightInformation(item) };
        for (Object o : values)
            sb.append(o);
        return sb.toString();
    }

    private static final int DEFAULT_WEIGHT = -1;

    private static Integer[] userWeights = null;

    private String getUserWeightInformation(Item item) {
        List<User> users = userManager.get();
        if (userWeights == null || userWeights.length != users.size()) {
            userWeights = new Integer[users.size()];
        }

        int i = 0;

        double totCount = item.getCount();
        int totWeights = 0;
        for (User u : users) {
            userWeights[i] = iuManager.getCount(item.getId(), u.getId());
            totWeights += userWeights[i];
            i++;
        }
        boolean isSame = true;
        int d = DEFAULT_WEIGHT;
        for (Integer w : userWeights) {
            if (d == DEFAULT_WEIGHT) {
                d = w;
            } else if (d != w) {
                isSame = false;
                break;
            }
        }
        StringBuffer sb = new StringBuffer();
        if (isSame) {
            sb.append("All");
        } else {
            for (i = 0; i < userWeights.length; i++) {
                double w = priceFormat(userWeights[i]*totCount/totWeights);
                User u = users.get(i);
                if (w != 0)
                    sb.append(u.getName()).append(":").append(w).append(";");
            }
        }
        return sb.toString();
    }

    public double priceFormat(double price) {
        return Math.round(price * 100) / 100.0;
    }

}
